package com.zjsru.oneDay202204;

import java.util.ArrayDeque;
import java.util.Deque;

/**
 * @Author: likew
 * @Date: 2022/5/2
 * 标签验证器
 *
 *输入: "<DIV>This is the first line <![CDATA[<div>]]></DIV>"
 *
 * 输出: True
 *
 * 解释:
 *
 * 代码被包含在了闭合的标签内： <DIV> 和 </DIV> 。
 *
 * TAG_NAME 是合法的，TAG_CONTENT 包含了一些字符和 cdata 。
 *
 * 即使 CDATA_CONTENT 含有不匹配的起始标签和不合法的 TAG_NAME，它应该被视为普通的文本，而不是标签。
 *
 * 所以 TAG_CONTENT 是合法的，因此代码是合法的。最终返回True。
 */
public class isValid {
    String CDATA1 = "<![CDATA[", CDATA2 = "]]>";
    public boolean isValid(String code) {
        Deque<String> d = new ArrayDeque<>();
        int n = code.length(), i = 0;
        while(i < n){
            if(i + 8 < n && code.substring(i,i+9).equals(CDATA1)){
                if(i == 0) return false;
                int j = i+9;
                boolean ok = false;
                while(j < n && !ok){
                    if(j + 2< n && code.substring(j,j+3).equals(CDATA2)){
                        j = j + 3;
                        ok = true;
                    }else{
                        j++;
                    }
                }
                if(!ok) return false;
                i = j;
            }else if(code.charAt(i) == '<'){
                if(i == n -1) return false;
                boolean isEnd = code.charAt(i + 1) == '/';
                int p = isEnd ? i + 2 : i + 1,j=p;
                while(j < n && code.charAt(j) != '>'){
                    if(!Character.isUpperCase(code.charAt(j))) return false;
                    j++;
                }
                if(j == n) return false;
                int len = j - p;
                if(len < 1 || len > 9) return false;
                String tag = code.substring(p,j);
                i = j+1;
                if(!isEnd){
                    d.addLast(tag);
                }else{
                    if(d.isEmpty() || !d.pollLast().equals(tag)) return false;
                    if(d.isEmpty() && i < n) return false;
                }
            }else{
                if(i == 0) return false;
                i++;
            }
        }
        return d.isEmpty();
    }
    
    public static void main(String[] args) {
        isValid isValid = new isValid();
        String code = "<DIV>This is the first line <![CDATA[<div>]]></DIV>";
        System.out.println(isValid.isValid(code));
    }
}
